import {
  Body,
  Controller,
  Get,
  Param,
  Post,
  Query,
  UseGuards,
} from '@nestjs/common';
import { ApiOperation, ApiTags } from '@nestjs/swagger';
import { DeptService } from './dept.service';
import { AuthGuard } from '@nestjs/passport';
import { Dept } from './dept.entity';
import { UserService } from 'src/user/user.service';
import { FindOptionsWhere, In, Not, getManager } from 'typeorm';
import { Forbidden, Http, NotFound } from 'src/util/http';
import { CurrentUser } from 'src/user/user.decorator';
import { UserSys } from 'src/user/userSys.entity';
import { DeptRoleEnum, RoleEnum } from 'src/role/role.enum';
import { UserGuard } from 'src/role/role.guard';

@ApiTags('部门')
@UseGuards(AuthGuard('jwt'))
@Controller('api/dept')
export class DeptController {
  constructor(
    private readonly deptService: DeptService,
    private readonly userService: UserService,
  ) {}

  @Get('get')
  @ApiOperation({ summary: '获取所有部门' })
  @UseGuards(UserGuard([]))
  async get(@CurrentUser() user: UserSys) {
    const relations = ['parent', 'member', 'member.user'];
    const result = await this.deptService.find(
      { system: { id: user.system.id } },
      relations,
    );
    return result;
  }

  @Get(':id/getBy')
  @ApiOperation({ summary: '获取部门by职场' })
  async getBy(@CurrentUser() user: UserSys, @Param('id') id) {
    if (user.role !== RoleEnum.boos) {
      return await this.get(user);
    }
    return await this.deptService.find({ system: { id } });
  }

  @Get('getinfo')
  @ApiOperation({ summary: '获取个人部门信息' })
  async getinfo(@CurrentUser() user: UserSys) {
    if (user.role === RoleEnum.boos || user.role === RoleEnum.director) {
    }
    if (user.role === RoleEnum.director) {
    }

    if (user.dept.deptRole === DeptRoleEnum.member) {
      return await this.userService.findsBy({
        role: RoleEnum.manager,
        dept: { id: user.dept.id },
      });
    }
  }

  @Get('getProjectDept')
  @ApiOperation({ summary: '获取项目部' })
  @UseGuards(UserGuard())
  async getProjectDept(@CurrentUser() user: UserSys) {
    return await this.deptService.find({
      system: { id: user.system.id },
      editable: true,
    });
  }

  @Post(':parent_id/add')
  @ApiOperation({ summary: '添加部门' })
  @UseGuards(UserGuard())
  async add(
    @Body() { name },
    @Param('parent_id') id: number,
    @CurrentUser() user: UserSys,
  ) {
    const parent = !id
      ? null
      : await this.deptService.dept.findOne({ where: { id } });
    const entity = this.deptService.dept.create({ name });
    entity.parent = parent;
    entity.system = user.system;
    return await this.deptService.dept.save(entity);
  }

  @Post(':id/upd')
  @ApiOperation({ summary: '修改部门信息' })
  @UseGuards(UserGuard())
  async upd(
    @Body() { name, parent, manager },
    @Param('id') id: number,
    @CurrentUser() user: UserSys,
  ) {
    if (parent === id) throw Forbidden;
    const p = await this.deptService.dept.findOne({
      where: { id: parent, system: { id: user.system.id } },
    });
    if (!p) throw Forbidden;
    await this.deptService.dept.update(
      {
        id,
        system: {
          id: user.system.id,
        },
        editable: true,
      },
      {
        name,
        parent: p,
      },
    );
    const where: FindOptionsWhere<UserSys> = {
      system: { id: user.system.id },
      dept: { id },
      role: RoleEnum.manager,
    };
    await this.userService.userSys.update(where, { role: RoleEnum.member });
    where.role = RoleEnum.member;
    where.id = In(manager);
    const result = await this.userService.userSys.update(where, {
      role: RoleEnum.manager,
    });
    if (result.affected === 0) {
      throw Http.forbidden('仅允许设置本部门的员工为经理');
    }
    return result;
  }

  @Get(':id/del')
  @ApiOperation({ summary: '删除部门' })
  @UseGuards(UserGuard([DeptRoleEnum.personnel, RoleEnum.director]))
  async del(@Param('id') id: number) {
    if (
      !!(await this.deptService.dept.findOne({
        where: {
          parent: {
            id,
          },
        },
      }))
    )
      throw Http.forbidden('拥有子部门时不得删除部门');
    if (
      await this.userService.userSys.exist({
        where: {
          dept: {
            id,
          },
        },
      })
    )
      throw Http.forbidden('只能删除空部门，请调整部门员工');
    return this.deptService.dept.delete(id);
  }

  @Post('transfer')
  @ApiOperation({ summary: '转移部门' })
  @UseGuards(UserGuard([DeptRoleEnum.personnel]))
  async transfer(@Body() { ids, depid }, @CurrentUser() user: UserSys) {
    const dept = await this.deptService.dept.findOne({ where: { id: depid } });
    return await this.userService.userSys.update(
      {
        id: In(ids),
        system: {
          id: user.system.id,
        },
        role: Not(RoleEnum.director),
      },
      {
        dept,
      },
    );
  }
}
